<?php

//
// +------------------------------------------------------------------------+
// | PHP Version 5.4                                                        |
// +------------------------------------------------------------------------+
// | Copyright (c) All rights reserved.                                     |
// +------------------------------------------------------------------------+
// | 世纪车来车往(北京）网络科技有限公司 版权所有！                         |
// | TEL:010-63732365  HOTLINE:400-6688-365  EMAIL:clcw@clcw.com.cn         |
// | $Revision: 1.0 $                                                       |
// +------------------------------------------------------------------------+
// | Author: songaimin@clcw.com.cn  Blog:http://blog.csdn.net/samxx8        |
// +------------------------------------------------------------------------+
//

namespace AuctionCore\Account;

use AuctionCore\AntNest\Sms;
use AuctionCore\System\AuctionException;
use \AuctionCore\Common\PhpMemcache;

/**
 * 帐号功能抽像类
 * @author       Administrator
 */
abstract class User {

    /**
     * 用户名
     * @var      String
     */
    protected $user_name;
    protected $uid;

    /**
     * 授权管理功能类
     * @var      int
     */
    protected $auth_object;

    /**
     * 构造
     * @param    String $user_name    用户名
     * @return   void
     */
    public function __construct($user_name) {
        if (is_numeric($user_name)) {
            $m = $this->_getModel();
            if (strlen($user_name) > 10) {
                //手机登录
                $uid_where = array('pwd_mobile' => $user_name);
            } else {
                //uid登录
                $uid_where = array('uid' => $user_name);
            }
            $uid_where = array_merge($uid_where, array('status' => 0));
            $info = $m->where($uid_where)->find();
            if (!$info['user_name'])
                AuctionException::make_throw('200008');
            $user_name = $info['user_name'];
        }
        //用户名登录
        $this->user_name = $user_name;
    }

    private function _getModel() {
        $auth_db_cfg = $this->auth_object->get_config();

        $m = M($auth_db_cfg["AUTH_USER"]);
        return $m;
    }

    /**
     * 配合属性“用户名”，修改密码 
     * 返回:true/false
     * 
     *   
     * @param    String $new_pwd    新密码
     * @return   boolean
     */
    public function change_password($new_pwd) {

        if (!$this->user_name)
            AuctionException::make_throw('200003');
        if (empty($new_pwd))
            AuctionException::make_throw('200004');

        $m = $this->_getModel();
        $sets = array('passwd' => md5($new_pwd));
        $ok = $m->where(array('user_name' => $this->user_name))->save($sets);
        return $ok;
    }

    /**
     * 配合属性“用户名”，修改密码 
     * 返回:true/false
     * 
     *   
     * @param    String $new_pwd    新密码
     * @return   boolean
     */
    public function change_md5_password($new_pwd) {

        if (!$this->user_name)
            AuctionException::make_throw('200003');
        if (empty($new_pwd))
            AuctionException::make_throw('200004');

        $u_info = $this->user_info();
        if($u_info['passwd']==$new_pwd)
            AuctionException::make_throw('200038');            

        $m = $this->_getModel();
        $sets = array('passwd' => $new_pwd);
        $ok = $m->where(array('user_name' => $this->user_name))->save($sets);
        return $ok;
    }

    /**
     * 检查密码是否正确，检查启用状态，登录或修改密码使用。
     * 返回：用户信息
     * @param    String $pwd    帐号密码
     * @return   Object
     */
    public function check_pwd($pwd) {
        $m = $this->_getModel();
        $info = $m->where("user_name='{$this->user_name}'")->find();
        if ($info['passwd'] == md5($pwd))
            return $info;
        else
            return false;
    }

    /**
     * 检查密码是否正确，检查启用状态，登录或修改密码使用。
     * 返回：用户信息
     * @param    String $pwd    帐号密码
     * @return   Object
     */
    public function check_md5_pwd($pwd) {
        $m = $this->_getModel();
        $info = $m->where("user_name='{$this->user_name}'")->find();
        if ($info['passwd'] == $pwd)
            return $info;
        else
            return false;
    }

    /**
     * 用户详细
     * @return   Object
     */
    public function user_info() {
        $m = $this->_getModel();
        $info = $m->where(array('user_name' => $this->user_name))->find();
        return $info;
    }

    /**
     * 用户详情
     * return Object
     */
    public function get_user_info_by_uid($uid){
        $m = $this->_getModel();
        $info = $m->where(array('uid' => $uid))->find();
        return $info;
    }
    /**
     * 用户详情
     * return Object
     */
    public function get_user_info_by_pwd_mobile($pwd_mobile){
        $m = $this->_getModel();
        $info = $m->where(array('pwd_mobile' => $pwd_mobile))->find();
        return $info;
    }
    /**
     * 修改帐号手机号码
     * @param    String $mobile    新手机号
     * @return   boolean
     */
    public function change_pwd_mobile($mobile) {
        return $this->change_mobile($mobile, 'pwd_mobile');
    }

    public function check_id_card($id_card){
        $m = $this->_getModel();
        return $m->where(['u_idcard'=>$id_card])->find();
    }

    /**
     * 修改短信手机号码
     * @param    String $mobile    新手机号
     * @return   boolean
     */
    public function change_sms_mobile($mobile) {
        return $this->change_mobile($mobile, 'sms_mobile');
    }

    private function change_mobile($mobile, $type = 'sms_mobile') {
        if (empty($mobile))
            AuctionException::make_throw('200007');
        try{
            $m = $this->_getModel();
            $sets = array($type => $mobile);
            $ok = $m->where(array('user_name' => $this->user_name))->save($sets);    
        }catch(\Exception $e){                        
            if($e->getCode()=='23000'){
                AuctionException::make_throw('200076');
            }else{
                throw $e;
            }
        }
        return $ok;
    }

    public function update($sets) {
        $m = $this->_getModel();
        $user_name = $this->user_name;
        $ok = $m->where("user_name='{$user_name}'")->save($sets);
        return $ok;
    }

    /**
     * 启用帐号
     * @return   void
     */
    public function enable() {
        $m = $this->_getModel();
        $ok = $m->where(array('user_name' => $this->user_name))->save(array('status' => '0'));
    }

    /**
     * 禁用帐号
     * @return   void
     */
    public function disable() {
        $m = $this->_getModel();
        $ok = $m->where(array('user_name' => $this->user_name))->save(array('status' => '1'));
    }

    /**
     * 设置员工所属分组
     * @param    int $group_id    组id
     * @return   int
     */
    public function set_group($group_id) {
        $user_info = $this->user_info();
        $group_users = array('uid' => $user_info['uid'], 'group_id' => $group_id);

        $auth_db_cfg = $this->auth_object->get_config();
        $m = M($auth_db_cfg["AUTH_GROUP_ACCESS"]);
        $ok = $m->add($group_users);
    }
    //用组标识设置用户属组
    public function set_group_by_title($title){
        $auth_db_cfg = $this->auth_object->get_config();
        $m = M($auth_db_cfg["AUTH_GROUP"]);
        $group_id = $m->getFieldByTitle($title,'id');
        return $this->set_group($group_id);
    }

    /**
     * 员工移出所属分组
     * @param    int $group_id    组id
     * @return   int
     */
    public function exgraft_group($group_id) {
        $user_info = $this->user_info();
        $auth_db_cfg = $this->auth_object->get_config();
        $m = M($auth_db_cfg["AUTH_GROUP_ACCESS"]);
        $where = "uid='{$user_info['uid']}' and group_id='{$group_id}'";
        $ok = $m->where($where)->delete();
        return $ok;
    }

    /**
     * 获取用户分组
     * @return   Object
     */
    public function get_groups() {
        $user_info = $this->user_info();
        $uid = $user_info['uid'];
        $groups = $this->auth_object->getGroups($uid);
        return $groups;
    }

    /**
     * 更新头像
     * @param $avatar 头像url地址
     * @return true/false;
     */
    public function change_avatar($avatar) {
        $m = $this->_getModel();
        $sets = array('avatar' => $avatar);
        $ok = $m->where(array('user_name' => $this->user_name))->save($sets);
        return $ok;
    }

    /**
     * 创建网站用户
     * @param array info [用户名，密码,昵称,手机号]
     * @pram is_md5 密码是否md5后
     * @return user_id
     */
    protected static function create($auth, $info,$is_md5=false) {

        if (empty($info['user_name']))
            AuctionException::make_throw('200001');
        if (empty($info['passwd']))
            AuctionException::make_throw('200002');

        $auth_db_cfg = $auth->get_config();
        $m = M($auth_db_cfg["AUTH_USER"]);
        if(!$is_md5)
            $info['passwd'] = md5($info['passwd']);

        $now = date("Y-m-d H:i:s", time());
        $time = time();
        $info['reg_date'] = $now;
        $info['last_modify_time'] = $now;
        $info['las_login_time'] = $now;
        
        //运营平台->审核通过创建用户不受限制
        if($info['reg_from'] != 5){
            /**
             * 限制IP注册次数
             */
           $reg_limit_config = \AuctionCore\System\SystemConf::getConfByName("REG_TIMES_LIMIT");
           $reg_limit_config = json_decode($reg_limit_config['value'],true);
   //        $reg_interval_time = empty($reg_limit_config['interval_time'])? 300 :$reg_limit_config['interval_time'];
           $reg_limit_num_ip = empty($reg_limit_config['reg_num_ip'])? 10 : $reg_limit_config['reg_num_ip'];
           $reg_ip = get_client_ip();
           $redis = new \AuctionCore\Common\PhpRedis();
            $arr = [
                'ip'=>$reg_ip,
            ];
            $keyName = getRedisKeyByCode('REDIS_KEY','100010',$arr);
            $quota = $redis->get($keyName);
           //$quota = $redis->get('reg_num_limit_ip_' . $reg_ip);
           if ($quota) {
               $quota_data = json_decode($quota, true);
   //            $interval_time = time() - $quota_data['time'];
   //            if ($interval_time < $reg_interval_time) {
   //                AuctionException::make_throw('100020');
   //            }
               if ($quota_data['num'] >= $reg_limit_num_ip) {
                   AuctionException::make_throw('100021');
               }
               $num = $quota_data['num'] + 1;
           } else {
               $num = 1;
           }
           $params = array('num' => $num);
           $diff_time = strtotime('tomorrow') - $time;
           $arr = [
                'ip'=>$reg_ip,
           ];
           $keyName = getRedisKeyByCode('REDIS_KEY','100010',$arr);

           if ($diff_time > 0) {
               //$redis->set('reg_num_limit_ip_'  . $reg_ip, json_encode($params), $diff_time);
               $redis->set($keyName, json_encode($params), $diff_time);
           } else {
               $redis->del($keyName);
               //$redis->del('reg_num_limit_ip_'  . $reg_ip);
               $params_init = array('num' => 1);
               $redis->set($keyName, json_encode($params_init));
           }
        }
        /**
         * 根据uuid限制每天注册次数
         */
        if(!empty($info['uuid'])){
            $reg_limit_num_uuid = empty($reg_limit_config['reg_num_uuid'])? 3 : $reg_limit_config['reg_num_uuid'];
            $quota_uuid = $redis->get('reg_num_limit_uuid_' . $info['uuid']);
            if ($quota_uuid) {
                $quota_uuid_data = json_decode($quota_uuid, true);
                if ($quota_uuid_data['num_uuid'] >= $reg_limit_num_uuid) {
                    AuctionException::make_throw('100022');
                }
                $num_uuid = $quota_uuid_data['num_uuid'] + 1;
            } else {
                $num_uuid = 1;
            }
            $params_uuid = array( 'num_uuid' => $num_uuid);
            $redis->set('reg_num_limit_uuid_' . $info['uuid'], json_encode($params_uuid));
        }
        $user_id = $m->add($info);
        /**
         * 添加注册日志
         */
        \AuctionCore\Account\RegLog::add_reg_log($user_id, $reg_ip, $info['uuid'], $info['reg_from']);
        return $user_id;
    }

    /**
     * 删除用户
     * @param string user_name 用户名
     * @return bool
     */
    protected static function remove($auth, $user_name) {

        if (empty($user_name))
            AuctionException::make_throw('200006');

        $auth_db_cfg = $auth->get_config();
        $m = M($auth_db_cfg["AUTH_USER"]);
        $ok = $m->where("user_name='" . $user_name . "'")->delete();
        return $ok;
    }

    //强制重置密码,并发送短信
    public function reset_password() {
        $new_password = rand(100000, 999999);
        //更新帐号密码
        $user_info = $this->user_info();
        if (!$user_info || !count($user_info) > 0) {
            AuctionException::make_throw('200008');
        }
        $mobile = $user_info['pwd_mobile'];
        $ok = $this->change_password($new_password);

        //发送密码
        if ($mobile) {
            $sms = new Sms();
            header('reset_new_pwd:' . $new_password);
            $sms->notify(1, $mobile, ['username' => $user_info['user_name'], 'password' => $new_password]);
        }
    }


    //不传密码，登录方式
    public static function loginByLoginKey($user_name,$login_key,$time){
        try{
            $front_user = new \AuctionCore\Account\FrontUser($user_name);
                    
            $info = $front_user->user_info();

            if($info['status']){
                AuctionException::make_throw('200010'); 
            }
            $pwd_md5 = $info['passwd'] ;
            if($info && $login_key == sha1($user_name.$info['passwd'].$time.C('auth')['salt'])){

                $mem = new PhpMemcache();
                if($mem->get('appapi_login_'.$login_key) || (time()-($time/1000))>30){                            
                    AuctionException::make_throw('100068');      
                }

                //更新互斥登录
                $ul = new \AuctionCore\Account\UniqLogin();
                $uniq_login_token = $ul->update($info['uid']);
                $info['uniq_login_token'] = $uniq_login_token;

                unset($info['passwd']);
                unset($info['status']); 

                //记录登录请求key
                $mem->set('appapi_login_'.$login_key, $user_name, 40);            
                return array($info,$pwd_md5);
            }else{
               AuctionException::make_throw('200022'); 
            }
        }catch(AuctionException $e){
            if($e->getCode()=='200008'){
                AuctionException::make_throw('200022');    
            }
            AuctionException::make_throw($e->getCode()); 
        }
    }

}